--
--
-- ***********************************************************************
--
--  Date de realisation:        Version 1997 (Ada-95)
--  Compilateur:                GNAT sur Windows-95 (version 3.10p)
--  Auteur:                     Jean-Marie RIGAUD
--                              IRIT Universite Paul Sabatier
--                              31062-TOULOUSE Cedex
--                              E-mail: rigaud@irit.fr
--  Portabilite                 totale
--
-- ***********************************************************************
--
--  
--                 ==================================
--                         GESTION DE TEXTES
--                 ==================================
--
--
--
--    Ce paquetage implemente des chaines de caracteres dont 
--     le nombre de caracteres effectifs peut varier durant
--     la vie de la variable.
--
--
--    Le type TEXTE est un type prive heritant du type controle
--      ce qui permet de disposer de l'operation d'affectation
--      et de traitements d'initialisation et de destructionh
--    Des operateurs specifiques permettent la manipulation  
--     des informations de ce type abstrait.
--
--    Les services sont les suivants:
--
--      - Le type TEXTE
--
--      - La constante TEXTE_NUL
--
--      - Des operations de conversion (types string et character)
--      - Des operations de consultation
--      - Des operations d'entrees-sorties
--      - Des operations de concatenation
--      - Des operations d'extraction et d'insertion
--      - Des operations de recherche
--      - Des operations de comparaison
--
--      - Une operation de test d'egalite
--
--
--
--
--   Des exceptions permettent d'avertir l'utilisateur en cas de mauvaise
--     utilisation des operations
--     ERREUR_TEXTE_INVALIDE
--	    Un parametre de type TEXTE ne contient pas une valeur correcte
--     ERREUR_PARAMETRE_INCORRECT
--        Un parametre de travail autre qu'un texte contient une valeur 
--        incorrecte
--
--  =====================================================================

with Ada.Finalization;
use  Ada;

package Gestion_De_Textes is


   -- ========================
   --  Le type TEXTE defini
   -- ========================

   type Texte is private; --new Finalization.Controlled with private;



   -- ========================
   -- Definition de constante
   -- ========================

   Texte_Nul : constant Texte;
   --  Constante definissant une chaine de longueur nulle


   -- =========================
   -- Definitions d' exceptions
   -- =========================

   Erreur_Texte_Invalide,
   Erreur_Parametre_Incorrect : exception;
   -- Exceptions levees chaque fois qu'un parametre d'appel d'une operation
   --  est incorrect.


   -- ============================
   -- Des operations de conversion 
   -- ============================
   --  Definition d'un TEXTE a partir d'une information de type
   --  "string" ou "character", fournie par l'utilisateur.

   function En_Texte (La_Chaine    : String)    return Texte;

   function En_Texte (Le_Caractere : Character) return Texte;


   -- ==============================
   -- Des operations de consultation
   -- ==============================
   --  Retourne le contenu d'un TEXTE, sous la forme d'un texte ou d'un "string"

   function Valeur (Le_Texte : Texte) return String;

   function Tranche (Le_Texte : Texte;
         Du_Rang  : Positive;
         Au_Rang  : Positive) return String;

   function Element (Le_Texte : Texte;
         Au_Rang  : Positive) return Character;

   -- ******************************

   function Longueur (Le_Texte : Texte) return Natural;
   --  Nombre de caracteres effectifs dans un TEXTE.


   -- ================================
   -- Des operations d'entrees-sorties
   -- ================================

   procedure Put (Le_Texte : in Texte;
         Format   : in Natural := 0);
   --  Affichage d'un TEXTE
   --  Un format permet de preciser la taille de la zone d'edition;
   --  - Lorsque le format est superieur a la longueur du texte,
   --    la chaine est completee (sur sa droite) par des espaces; 
   --  - Lorsque le format est inferieur ou egal a la longueur du texte
   --    la chaine est affichee en totalite (on ignore le format).


   -- ******************************

   procedure Get (Le_Texte : in out Texte;
         Format   : in Natural);
   --  Saisie d'un TEXTE au clavier de l'utilisateur.
   --  Un format permet de preciser le nombre de caracteres a entrer. 

   -- ******************************

   procedure Get_Line (Le_Texte : in out Texte);
   --  Saisie d'un TEXTE au clavier de l'utilisateur.
   --  Tous les caracteres jusqu'au termine-ligne sont pris en compte.


   -- ===============================
   -- Des operations de concatenation
   -- ===============================

   function "&" (Op_G : Texte;
         Op_D : Texte) return Texte;

   function "&" (Op_G : Texte;
         Op_D : String) return Texte;

   function "&" (Op_G : Texte;
         Op_D : Character) return Texte;

   function "&" (Op_G : String;
         Op_D : Texte) return Texte;

   function "&" (Op_G : Character;
         Op_D : Texte) return Texte;


   -- ==========================
   -- Des operations d'insertion
   -- ==========================

   --  Insertion d'une information de type TEXTE, "string" ou "character" 
   --  a l'interieur d'une information de type TEXTE.
   --  Un parametre, de type "natural", permet de preciser a quel rang 
   --  doit etre realisee l'insertion.

   procedure Inserer (Le_Texte : in Texte;
         Dans     : in out Texte;
         Au_Rang  : in Natural := 1);

   -- ********************************************

   procedure Inserer (La_Chaine : in String;
         Dans      : in out Texte;
         Au_Rang   : in Natural := 1);

   -- ********************************************

   procedure Inserer (Le_Caractere : in Character;
         Dans         : in out Texte;
         Au_Rang      : in Natural := 1);


   -- ==============================
   -- Des operations de modification
   -- ==============================
   --  Les operations suivantes permettent de modifier le contenu d'un texte par 
   --    modification d'un caractere ou d'une tranche de caracteres

   procedure Modifier (Le_Texte      : in out Texte;
         Au_Rang       : in Positive;
         Par_Caractere : in Character);

   procedure Modifier (Le_Texte    : in out Texte;
         Du_Rang     : in Positive;
         Au_Rang     : in Positive;
         Par_Tranche : in String);


   -- ===========================
   -- Des operations d'extraction
   -- ===========================
   --  Extraction d'une chaine de caracteres depuis une autre chaine.
   --  La chaine origine n'est pas modifiee;
   --  La chaine a extraire est definie par le rang du premier caractere
   --  et le rang du dernier caractere.

   procedure Extraire (Depuis  : in Texte;
         Vers    : in out Texte;
         Du_Rang : in Natural;
         Au_Rang : in Natural);


   -- ===========================
   -- Des operations de recherche
   -- ===========================
   -- Recherche de la chaine fournie en premier parametre, dans le
   --  TEXTE fourni en deuxieme parametre. 
   -- Retourne le rang du premier caractere dans le TEXTE "DANS", lorsque
   --  la chaine est trouvee, retourne 0 (zero) sinon.

   function Rang_De (Le_Texte : Texte;
         Dans : Texte) return Natural;

   function Rang_De (La_Chaine : String;
         Dans : Texte) return Natural;

   function Rang_De (Le_Caractere : Character;
         Dans : Texte) return Natural;

   -- =============================
   -- Des operations de comparaison
   -- =============================
   --  Operateurs de relations entre deux informations de type TEXTE

   function "<" (Op_G : Texte;
         Op_D : Texte) return Boolean;

   function "<=" (Op_G : Texte;
         Op_D : Texte) return Boolean;

   function ">" (Op_G : Texte;
         Op_D : Texte) return Boolean;

   function ">=" (Op_G : Texte;
         Op_D : Texte) return Boolean;


   -- ===============================
   -- Une operation de test d'egalite
   -- ===============================

   function "=" (Op_G : Texte;
         Op_D : Texte) return Boolean;


   --  ======================================
   --       Implementation du type TEXTE
   --  ======================================


private



   --  Le type TEXTE est defini comme un pointeur sur une structure 
   --  a discriminant contenant la chaine de caracteres de la chaine. 
   --  La declaration d'un objet de type TEXTE ne genere donc pas 
   --  la place necessaire pour contenir une chaine de caracteres. Ce sont 
   --  les manipulations qui suivent qui sont chargees de reserver la place 
   --  necessaire pour les caracteres de la chaine. 
   --  La constante CHAINE_NULLE est un pointeur vers une chaine de zero 
   --  caracteres.


   --------------------------------------------

   type Une_Chaine (Taille : Natural) is
   record
      Valeur : String (1 .. Taille);
   end record;

   --------------------------------------------

   type Un_Texte is access Une_Chaine;

   type Texte is new Finalization.Controlled with
   record
      T : Un_Texte;
   end record;
   
   -- =====================================
   -- Les operations heritees et redefinies
   -- =====================================

   procedure Initialize (X : in out Texte);

   procedure Adjust     (X : in out Texte);

   procedure Finalize   (X : in out Texte);


   Texte_Nul : constant Texte := (Finalization.Controlled with (new Une_Chaine (0)));


end Gestion_De_Textes;
